﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace CalculadoraDeMatrizes
{
    class Gerador
    {
        private string[] opcoesMatrizes = { "SOMAR", "SUBTRAIR", "MULTIPLICAR", "TRANSPOSTA", "OPOSTA", "DETERMINANTE 2X2",
                                             "INVERSA 2X2","DETERMINANTE 3X3"};

        private TextBox[,] Matriz1;
        private TextBox[,] Matriz2;
        private TextBox[,] Matriz3;

        private List<TextBox> allTextBox;

        public TextBox[,] getMatriz1() { return Matriz1; }
        public TextBox[,] getMatriz2() { return Matriz2; }
        public TextBox[,] getMatriz3() { return Matriz3; }

        public void setMatriz3(int x, int y, string valor) { Matriz3[x, y].Text = valor; }

        #region Singleton
        private Gerador()
        {
            Matriz1 = new TextBox[2, 2];
            Matriz2 = new TextBox[2, 2];
            Matriz3 = new TextBox[2, 2];

            allTextBox = new List<TextBox>();
        }

        private static Gerador gerador = null;
        public static Gerador getInstance()
        {
            if (gerador == null)
                gerador = new Gerador();

            return gerador;
        }
        #endregion

        /// <summary>
        /// Adicionará todos os cálculos de matriz possíveis na ComboBox da aplicação
        /// </summary>
        /// <param name="comboBox">ComboBox que será adicionado os items</param>
        public void Gerador_ComboBox(ComboBox comboBox)
        {
            for (int i = 0; i < opcoesMatrizes.Length; i++)
                comboBox.Items.Add(opcoesMatrizes[i]);

            comboBox.Text = "Escolha a operação desejada";
        }

        /// <summary>
        /// Gerará as caixas de texto onde o usuário poderá inserir os valores nas matrizes
        /// </summary>
        /// <param name="opcoesSelecionada">Texto atual do ComboBox</param>
        public int Gerador_TextBox(string opcoesSelecionada, int matriz1_1, int matriz1_2, int matriz2_1, int matriz2_2)
        {
            DestruirTextBox();

            //SOMAR - SUBTRAIR - MULTIPLICAR
            if (opcoesSelecionada.Equals(opcoesMatrizes[0]) || opcoesSelecionada.Equals(opcoesMatrizes[1]) ||
                opcoesSelecionada.Equals(opcoesMatrizes[2]))
            {
                CriarTextBox(matriz1_1, matriz1_2, matriz2_1, matriz2_2);

                //Adicionar as matrizes 2x2.
                return 1;
            }

            // TRANSPOSTA
            else if (opcoesSelecionada.Equals(opcoesMatrizes[3]))
            {
                CriarTextBox(matriz1_1, matriz1_2, true);

                //Adicionar as matrizes 2x2.
                return 3;
            }

            //OPOSTA
            else if (opcoesSelecionada.Equals(opcoesMatrizes[4]))
            {
                CriarTextBox(matriz1_1, matriz1_2, false);

                //Adicionar as matrizes 2x2.
                return 3;
            }

            //DETERMINATE 2X2
            else if (opcoesSelecionada.Equals(opcoesMatrizes[5]))
            {
                CriarTextBox(2, 2, 2, 2);

                //Adicionar as matrizes 2x2.
                return 2;
            }

            //INVERSA 2X2
            else if (opcoesSelecionada.Equals(opcoesMatrizes[6]))
            {
                CriarTextBox(2, 2, false);

                //Adicionar as matrizes 2x2.
                return 3;
            }

            //DETERMINANTE 3X3
            else if (opcoesSelecionada.Equals(opcoesMatrizes[7]))
            {
                CriarTextBox(3, 3, 3, 3);

                //Adicionar as matrizes 2x2.
                return 2;
            }

            return -1;
        }

        private void CriarTextBox(int matriz1_1, int matriz1_2, int matriz2_1, int matriz2_2)
        {
            int posX = 50, posX2 = 245, posX3 = 50, posY = 190, posY3 = 320;
            int tamanhoX = 40, tamanhoY = 20;
            int contador = 0;
            int XMaximo = 0, yMaximo = 0;

            Matriz1 = new TextBox[matriz1_1, matriz1_2];

            //Matriz à esquerda
            for (int x = 0; x < matriz1_1; x++)
            {
                for (int y = 0; y < matriz1_2; y++)
                {
                    TextBox tb = new TextBox();
                    tb.Location = new Point(posX, posY);
                    tb.Size = new Size(tamanhoX, tamanhoY);
                    tb.TabIndex = contador + 1;
                    tb.Text = "0";
                    tb.MaxLength = 4;
                    posX += tamanhoX + 3;
                    XMaximo = posX;
                    yMaximo = posY;

                    Matriz1[x, y] = tb;
                    contador++;
                    allTextBox.Add(Matriz1[x, y]);
                }

                posY += tamanhoY + 3;
                posX = 50;
            }

            //Resetar as posições
            posY = 190;
            posX2 = XMaximo + 20;

            Matriz2 = new TextBox[matriz2_1, matriz2_2];
            //Matriz à direita
            for (int x = 0; x < Matriz2.GetLength(0); x++)
            {
                for (int y = 0; y < Matriz2.GetLength(1); y++)
                {
                    TextBox tb = new TextBox();
                    tb.Location = new Point(posX2, posY);
                    tb.Size = new Size(tamanhoX, tamanhoY);
                    tb.TabIndex = contador + 1;
                    tb.Text = "0";
                    tb.MaxLength = 4;
                    posX2 += tamanhoX + 3;

                    if (yMaximo < posY)
                        yMaximo = posY;

                    Matriz2[x, y] = tb;
                    contador++;
                    allTextBox.Add(Matriz2[x, y]);
                }

                posY += tamanhoY + 3;
                posX2 = XMaximo + 20;
            }

            Matriz3 = new TextBox[matriz1_1, matriz2_2];
            posY3 = yMaximo + 40;
            posX3 = (posX + XMaximo) / 2;
            //Matriz abaixo
            for (int x = 0; x < Matriz3.GetLength(0); x++)
            {
                for (int y = 0; y < Matriz3.GetLength(1); y++)
                {
                    TextBox tb = new TextBox();
                    tb.Location = new Point(posX3, posY3);
                    tb.Size = new Size(tamanhoX, tamanhoY);
                    tb.TabIndex = contador + 1;
                    tb.Text = "0";
                    tb.MaxLength = 4;
                    posX3 += tamanhoX + 3;

                    Matriz3[x, y] = tb;
                    Matriz3[x, y].Enabled = false;
                    contador++;
                    allTextBox.Add(Matriz3[x, y]);
                }

                posY3 += tamanhoY + 3;
                posX3 = (posX + XMaximo) / 2;
            }
        }

        private void CriarTextBox(int matriz1_1, int matriz1_2, bool isTransposta)
        {
            int posX = 50, posX2 = 245, posX3 = 50, posY = 190, posY3 = 320;
            int tamanhoX = 40, tamanhoY = 20;
            int contador = 0;
            int XMaximo = 0, yMaximo = 0;

            Matriz1 = new TextBox[matriz1_1, matriz1_2];

            //Matriz à esquerda
            for (int x = 0; x < matriz1_1; x++)
            {
                for (int y = 0; y < matriz1_2; y++)
                {
                    TextBox tb = new TextBox();
                    tb.Location = new Point(posX, posY);
                    tb.Size = new Size(tamanhoX, tamanhoY);
                    tb.TabIndex = contador + 1;
                    tb.Text = "0";
                    tb.MaxLength = 4;
                    posX += tamanhoX + 3;
                    XMaximo = posX;
                    yMaximo = posY;

                    Matriz1[x, y] = tb;
                    contador++;
                    allTextBox.Add(Matriz1[x, y]);
                }

                posY += tamanhoY + 3;
                posX = 50;
            }

            //Resetar as posições
            posY = 190;
            posX2 = XMaximo + 20;


            if (isTransposta)
                Matriz3 = new TextBox[matriz1_2, matriz1_1];
            else
                Matriz3 = new TextBox[matriz1_1, matriz1_2];

            posY3 = yMaximo + 40;
            posX3 = 50;
            //Matriz abaixo
            for (int x = 0; x < Matriz3.GetLength(0); x++)
            {
                for (int y = 0; y < Matriz3.GetLength(1); y++)
                {
                    TextBox tb = new TextBox();
                    tb.Location = new Point(posX3, posY3);
                    tb.Size = new Size(tamanhoX, tamanhoY);
                    tb.TabIndex = contador + 1;
                    tb.Text = "0";
                    tb.MaxLength = 4;
                    posX3 += tamanhoX + 3;

                    Matriz3[x, y] = tb;
                    Matriz3[x, y].Enabled = false;
                    contador++;
                    allTextBox.Add(Matriz3[x, y]);
                }

                posY3 += tamanhoY + 3;
                posX3 = 50;
            }
        }

        /// <summary>
        /// Garantir que não sejam criados caixas de texto sobre as antigas.
        /// </summary>
        private void DestruirTextBox()
        {
            try
            {
                foreach (TextBox tb in allTextBox)
                {
                    tb.Dispose();
                }

                TextBox[] tbA = allTextBox.ToArray();
                allTextBox.RemoveRange(0, tbA.Length);
            }
            catch (NullReferenceException NRE) { Console.Write(NRE.Data); }
        }
    }
}